#include "LockGuard.hpp"
#include "BlockQueue.hpp"
#include "Task.hpp"
#include <ctime>
#include <unistd.h>
#include <iostream>

void* Comsumer(void* args)
{
    BlockQueue<Task> *bq = static_cast<BlockQueue<Task>*>(args);

    while(true)
    {
        Task task;
        bq->pop(&task);
        task();
        std::cout << task.PrintResult() << std::endl;

        // Task* ptask;
        // bq->pop(ptask);
        // ptask->Run();
        // std::cout << ptask->PrintResult() << std::endl;
    }
}

void* Productor(void* args)
{
    BlockQueue<Task> *bq = static_cast<BlockQueue<Task>*>(args);

    while(true)
    {
        int left = rand() % 100;
        usleep(rand()%100);
        int right = rand()% 100;
        usleep(rand()%100);
        char oper = Task::opers[rand() % Task::opers.size()];

        Task task(left, right, oper);
        bq->push(task);
        std::cout << task.PrintTask() << std::endl;
        // sleep(1);
    }
}

int main()
{
    srand(time(nullptr));
    BlockQueue<Task> *bq = new BlockQueue<Task>();
    pthread_t c[3], p[2];

    pthread_create(&c[0], nullptr, Comsumer, bq);
    pthread_create(&c[1], nullptr, Comsumer, bq);
    pthread_create(&c[2], nullptr, Comsumer, bq);

    pthread_create(&p[0], nullptr, Productor, bq);
    pthread_create(&p[1], nullptr, Productor, bq);

    pthread_join(c[0], nullptr);
    pthread_join(c[1], nullptr);
    pthread_join(c[2], nullptr);

    pthread_join(p[0], nullptr);
    pthread_join(p[1], nullptr);

    
}